#include "stdafx.h"
#include "Camera.h"
#include "Globals.h"

Camera::Camera()
{
	m_maScale.SetIdentity();
	m_maRotate.SetIdentity();
	m_maTranslate.SetIdentity();

	m_maWorld.SetIdentity();
	m_maView.SetIdentity();
	m_maProjection.SetIdentity();

	m_vPosition = Vector3(0.0f, 0.0f, -3.0f);
	m_vTarget = Vector3(0.0f, 0.0f, 0.0f);
	m_vUp = Vector3(0.0f, 1.0f, 0.0f);

	//Setup perspective
	GLfloat aspect;
	aspect = (GLfloat)Globals::screenWidth / (GLfloat)Globals::screenHeight;
	m_maPerspective.SetIdentity();
	m_maPerspective.SetPerspective(45.0f, aspect, 1.0f, 20.0f);
}

void Camera::SetPosition(Vector3 position)
{
	m_vPosition.x = position.x;
	m_vPosition.y = position.y;
	m_vPosition.z = position.z;
}

void Camera::SetTarget(Vector3 target)
{
	m_vTarget.x = target.x;
	m_vTarget.y = target.y;
	m_vTarget.z = target.z;
}

void Camera::SetUp(Vector3 up)
{
	m_vUp.x = up.x;
	m_vUp.y = up.y;
	m_vUp.z = up.z;
}

Matrix Camera::GetWVPMatrix()
{
	m_maView = (m_maScale * m_maRotate * m_maTranslate) * m_maPerspective;
	return m_maWorld * m_maView * m_maProjection;
}

Matrix Camera::GetInvWVPMatrix()
{
	Matrix maInvScale = Matrix (m_maScale);
	//Invert Scale

	Matrix maInvRotate = Matrix (m_maRotate);
	maInvRotate.Transpose();

	Matrix maInvTraslate = Matrix (m_maTranslate);
	maInvTraslate.m[3][0] *= -1.0f;
	maInvTraslate.m[3][1] *= -1.0f;
	maInvTraslate.m[3][2] *= -1.0f;

	m_maView = (maInvTraslate * maInvRotate) * m_maPerspective;
	//m_maView.SetIdentity();
	return m_maWorld * m_maView * m_maProjection;
}

void Camera::Update(ESContext *esContext, GLfloat deltaTime)
{
	//calculate rotation matrix
	Vector3 zaxis = (m_vPosition - m_vTarget).Normalize();
	Vector3 xaxis = (m_vUp.Cross(zaxis)).Normalize();
	Vector3 yaxis = (zaxis.Cross(xaxis)).Normalize();

	m_maRotate.m[0][0] = xaxis.x;	m_maRotate.m[0][1] = xaxis.y;	m_maRotate.m[0][2] = xaxis.z;	m_maRotate.m[0][3] = 0.0f;
	m_maRotate.m[1][0] = yaxis.x;	m_maRotate.m[1][2] = yaxis.y;	m_maRotate.m[1][2] = yaxis.z;	m_maRotate.m[1][3] = 0.0f;
	m_maRotate.m[2][0] = zaxis.x;	m_maRotate.m[2][1] = zaxis.y;	m_maRotate.m[2][2] = zaxis.z;	m_maRotate.m[2][3] = 0.0f;
	m_maRotate.m[3][0] = 0.0f;		m_maRotate.m[3][1] = 0.0f;		m_maRotate.m[3][2] = 0.0f;		m_maRotate.m[3][3] = 1.0f;

	//calculate translate matrix
	m_maTranslate.m[3][0] = m_vPosition.x;
	m_maTranslate.m[3][1] = m_vPosition.y;
	m_maTranslate.m[3][2] = m_vPosition.z;
}